﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using lumo;
using Microsoft.Xna.Framework;
using lumo.display.object2D;
using Microsoft.Xna.Framework.Graphics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;

namespace game.character.bullet
{
    /// <summary>
    /// Bullet class.
    /// </summary>
    public abstract class Bullet : Particle
    {

        public Texture2D Texture = null;
        public Vector2 Origin = Vector2.Zero;
        public Rectangle? SrcRect = null;
        public bool Destroyed = false;
        public int Damage;
        protected FarseerPhysics.Dynamics.Body BulletBody;

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="origin">Origin</param>
        /// <param name="target">Target</param>
        public Bullet(Microsoft.Xna.Framework.Graphics.Texture2D texture,
                Microsoft.Xna.Framework.Vector2 origin, Microsoft.Xna.Framework.Vector2 target,
                Microsoft.Xna.Framework.Vector2 additionalVelocity)
            : base()
        {
            // Set the body position.
            Microsoft.Xna.Framework.Vector2 Normal = Microsoft.Xna.Framework.Vector2.Normalize(target - origin);
            Texture = texture;
            Origin = new Microsoft.Xna.Framework.Vector2(texture.Width / 2, texture.Height / 2);
            LinearPosition = origin + Microsoft.Xna.Framework.Vector2.Multiply(Normal, 32f);

            // Setup the body.
            BulletBody = FarseerPhysics.Factories.BodyFactory.CreateCircle(Global.Map.World, (texture.Width / 2) / Global.PhysicsScale, 0.1f);
            BulletBody.BodyType = FarseerPhysics.Dynamics.BodyType.Dynamic;
            BulletBody.IsBullet = true;
            BulletBody.UserData = this;
            BulletBody.LinearDamping = 0;
            BulletBody.Position = Microsoft.Xna.Framework.Vector2.Divide(LinearPosition, Global.PhysicsScale);
            BulletBody.LinearVelocity = Microsoft.Xna.Framework.Vector2.Multiply(Normal, 1000.0f / Global.PhysicsScale) + additionalVelocity;
            BulletBody.OnCollision += OnCollision;
        }

        /// <summary>
        /// Update the bullet.
        /// </summary>
        /// <param name="Game"></param>
        /// <param name="Bullet"></param>
        public virtual void Update(LumoComponent Game, BulletManager Bullet)
        {
            if (!Destroyed)
                LinearPosition = Microsoft.Xna.Framework.Vector2.Multiply(BulletBody.Position, Global.PhysicsScale);
        }

        /// <summary>
        /// On Collision Method
        /// </summary>
        public abstract bool OnCollision(FarseerPhysics.Dynamics.Fixture fixtureA,
            FarseerPhysics.Dynamics.Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact);

        /// <summary>
        /// Called to do the cleanup.
        /// </summary>
        public virtual void OnDestroy()
        {
            // Collides with level.
            if (BulletBody != null)
                Global.Map.World.RemoveBody(BulletBody);
            BulletBody = null;
        }

        /// <summary>
        /// Override Alive method.
        /// </summary>
        public override bool Alive { get { return !Destroyed; } }
    }
}
